use actix_cors::Cors;
use actix_web::http::header;

pub fn cors() -> Cors {
    Cors::default()
        .allowed_origin_fn(|origin, _req_head| {
            // In production, you should validate origins more strictly
            origin.as_bytes().starts_with(b"http://localhost") ||
            origin.as_bytes().starts_with(b"https://localhost") ||
            origin.as_bytes().starts_with(b"http://127.0.0.1") ||
            origin.as_bytes().starts_with(b"https://127.0.0.1")
        })
        .allowed_methods(vec!["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"])
        .allowed_headers(vec![
            header::AUTHORIZATION,
            header::ACCEPT,
            header::CONTENT_TYPE,
            header::HeaderName::from_static("x-request-id"),
        ])
        .expose_headers(vec![
            header::HeaderName::from_static("x-request-id"),
        ])
        .max_age(3600)
        .supports_credentials()
}

#[cfg(test)]
mod tests {
    use super::*;
    use actix_web::{test, web, App, HttpResponse};

    async fn test_handler() -> HttpResponse {
        HttpResponse::Ok().json(serde_json::json!({"message": "test"}))
    }

    #[actix_web::test]
    async fn test_cors_middleware() {
        let app = test::init_service(
            App::new()
                .wrap(cors())
                .route("/test", web::get().to(test_handler))
        ).await;

        let req = test::TestRequest::get()
            .uri("/test")
            .insert_header(("Origin", "http://localhost:3000"))
            .to_request();
            
        let resp = test::call_service(&app, req).await;
        assert!(resp.status().is_success());
    }
}